#include "vl_terminator.h"
#include "vl_tunnel.h"

using namespace VL;


/**
 * @Author: CimZzz
 * @Date: 2022-07-15 12:13:58
 * 
 * 构造方法
 */
Terminator::Terminator(): dataFlow(Terminator::DataFlow::NoneDataFlow), operTunnel(nullptr) {

}



/**
 * @Author: CimZzz
 * @Date: 2022-07-19 16:59:20
 * 
 * 析构函数
 */
Terminator::~Terminator() {
	if(this->operTunnel != nullptr) {
		switch(this->dataFlow) {
			case Terminator::DataFlow::InputDataFlow:
				this->operTunnel->inTerminator = nullptr;
			break;
			case Terminator::DataFlow::OuputDataFlow:
				this->operTunnel->inTerminator = nullptr;
			break;
			default:
			break;
		}
	}
}


/**
 * @Author: CimZzz
 * @Date: 2022-07-15 14:10:43
 * 
 * 安装管道消息回调
 * @param messageCallback 管道消息回调
 */
void Terminator::setupMessageCallback(MessageCallback messageCallback) {
	this->messageCallback = messageCallback;
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-15 14:11:16
 * 
 * 安装管道数据回调
 * @param dataCallback 管道数据回调
 */
void Terminator::setupDataCallback(Terminator::DataCallback dataCallback) {
	this->dataCallback = dataCallback;
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-19 15:44:43
 * 
 * 向指定管道输入数据
 * @param tunnel 管道指针
 * 
 * @return 返回管道指针
 * 
 * @note 如果当前管道不出于顶端, 将会一直遍历到顶部管道为止
 */
BaseTunnel* Terminator::input(BaseTunnel* tunnel) {
	this->dataFlow = Terminator::DataFlow::InputDataFlow;
	auto tunnelPtr = tunnel;
	while(tunnelPtr->lastTunnel != nullptr) {
		tunnelPtr = tunnelPtr->lastTunnel;
	}
	this->operTunnel = tunnel;
	this->operTunnel->inTerminator = this;
	return tunnel;
}



/**
 * @Author: CimZzz
 * @Date: 2022-07-15 12:12:50
 * 
 * 向指定管道输出数据
 * @param tunnel 管道指针
 * 
 * @note 如果当前管道不出于底端, 将会一直遍历到底部管道为止
 */
void Terminator::output(BaseTunnel* tunnel) {
	this->dataFlow = Terminator::DataFlow::OuputDataFlow;
	auto tunnelPtr = tunnel;
	while(tunnelPtr->nextTunnel != nullptr) {
		tunnelPtr = tunnelPtr->nextTunnel;
	}
	this->operTunnel = tunnel;
	this->operTunnel->outTerminator = this;
}



/**
 * @Author: CimZzz
 * @Date: 2022-07-19 16:57:37
 * 
 * 重置当前终端的管道
 * 
 * * 重置为无管道状态
 */
void Terminator::resetTunnel() {
	this->dataFlow = Terminator::DataFlow::NoneDataFlow;
	if(this->operTunnel != nullptr) {
		this->operTunnel->outTerminator = nullptr;
		this->operTunnel = nullptr;
	}
}


/**
 * @Author: CimZzz
 * @Date: 2022-07-15 12:02:33
 * 
 * 向管道传递数据
 * @param data 数据指针
 */
void Terminator::passData(const std::shared_ptr<TunnelData>& data) {
	if(this->operTunnel == nullptr) {
		return;
	}
	switch(this->dataFlow) {
		case Terminator::DataFlow::InputDataFlow:
			this->operTunnel->doPass(data);
		break;
		case Terminator::DataFlow::OuputDataFlow:
			this->operTunnel->doReply(data);
		break;
		default:
		break;
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-19 17:34:05
 * 
 * 销毁整个数据管道
 */
void Terminator::destroyAll() {
	if(this->operTunnel != nullptr) {
		this->operTunnel->destroyAll();
	}
}


/**
 * @Author: CimZzz
 * @Date: 2022-07-15 12:21:15
 * 
 * 接收来自管道的消息
 * 
 * * 供管道调用
 * 
 * @param message 管道消息指针
 */
void Terminator::recvTunnelMessage(const std::shared_ptr<TunnelMessage>& message) {
	if(this->messageCallback) {
		this->messageCallback(message);
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-15 14:07:24
 * 
 * 接收来自管道的数据
 * 
 * * 供管道调用
 * 
 * @param data 管道数据指针
 */
void Terminator::recvTunnelData(const std::shared_ptr<TunnelData>& data) {
	if(this->dataCallback) {
		this->dataCallback(data);
	}
}